package pl.edu.agh.pros.proxy.view.xmpp;

import java.util.Arrays;
import java.util.Collection;

import pl.edu.agh.pros.proxy.logic.dao.XmppServerConfigurationDAO;
import pl.edu.agh.pros.proxy.model.XmppServerConfiguration;

import com.google.appengine.api.datastore.Key;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItem;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class XmppServersLayout extends VerticalLayout {

	private static final ThemeResource icon1 = new ThemeResource("images/add.png");
	private static final ThemeResource icon2 = new ThemeResource("images/delete.png");

	private static final XmppServerConfigurationDAO XMPP_DAO = XmppServerConfigurationDAO.getInstance();
	private Collection<XmppServerConfiguration> configurations;
	private XmppServerConfiguration newConfiguration;
	private XmppServerConfiguration selectedConfiguration;
	private XmppServersForm editForm;
	private XmppServersTable table;

	public XmppServersLayout(final Key providerKey) {

		if (providerKey != null) {
			configurations = XMPP_DAO.getXmppServers(providerKey);
		}

		HorizontalLayout horizontalLayout = new HorizontalLayout();

		// Bind a table to it
		table = new XmppServersTable(configurations);

		final Button newButton = new Button("New");
		final Button deleteButton = new Button("Delete");

		horizontalLayout.addComponent(table);
		horizontalLayout.setSpacing(true);

		editForm = new XmppServersForm();
		editForm.setVisible(false);
		horizontalLayout.addComponent(editForm);

		// When the user selects an item, show it in the form
		table.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				newConfiguration = null;
				if (event.getProperty().getValue() == null) {
					editForm.setVisible(false);
				} else {
					selectedConfiguration = (XmppServerConfiguration) event.getProperty().getValue();
					deleteButton.setEnabled(true);
					editForm.setItemDataSource(table.getItem(table.getValue()));
					showForm("Edit Item");
				}
			}
		});

		HorizontalLayout buttonsLayout = new HorizontalLayout();
		buttonsLayout.setSpacing(true);

		newButton.setIcon(icon1);
		newButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				newConfiguration = new XmppServerConfiguration();
				selectedConfiguration = null;
				BeanItem<XmppServerConfiguration> beanItem = new BeanItem<XmppServerConfiguration>(newConfiguration);
				editForm.setItemDataSource(beanItem);
				showForm("Create Item");
				newButton.setEnabled(false);
			}
		});

		deleteButton.setIcon(icon2);
		deleteButton.setEnabled(false);
		deleteButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				if (table.getValue() != null) {
					editForm.setVisible(false);
					table.removeItem(table.getValue());
					table.commit();
					table.setValue(null);
					deleteButton.setEnabled(false);
					newButton.setEnabled(true);
					XMPP_DAO.delete(selectedConfiguration);
				}
			}
		});
		buttonsLayout.addComponent(newButton);
		buttonsLayout.addComponent(deleteButton);
		addComponent(buttonsLayout);
		addComponent(horizontalLayout);

		final Button submitButton = new Button("Save");
		submitButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				editForm.commit();
				editForm.setVisible(false); // and close it
				table.setValue(null);

				// New items have to be added to the container
				if (newConfiguration != null) {
					table.getContainerDataSource().addItem(newConfiguration);
					table.commit();
					newButton.setEnabled(true);
					XMPP_DAO.saveNewConfiguration(newConfiguration, providerKey);
				} else if (selectedConfiguration != null) {
					XMPP_DAO.save(selectedConfiguration);
				}
			}
		});
		editForm.getFooter().addComponent(submitButton);

		Button cancel = new Button("Cancel");
		cancel.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				editForm.discard(); // Not really necessary
				editForm.setVisible(false); // and close it
				table.discard(); // Discards possible addItem()
				table.setValue(null);
				newConfiguration = null;
				selectedConfiguration = null;
				newButton.setEnabled(true);
			}
		});
		editForm.getFooter().addComponent(cancel);
	}

	public XmppServersTable getTable() {
		return table;
	}

	private void showForm(String caption) {
		editForm.setCaption(caption);
		editForm.setVisibleItemProperties(Arrays.asList(new String[] { "hostname", "port", "conferenceService" }));
		editForm.setVisible(true);
	}

}